home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Mac / Modules / mactcp / tcpglue.c < prev    next >
Text File  |  1995-01-18  |  10KB  |  478 lines

  1. /*
  2.  * Glue routines for mactcp module.
  3.  * Jack Jansen, CWI, 1994.
  4.  *
  5.  * Adapted from mactcp socket library, which was in turn
  6.  * adapted from ncsa telnet code.
  7.  *
  8.  * Original authors: Tom Milligan, Charlie Reiman
  9.  */
  10.  
  11. # include <Memory.h>
  12. # include <Files.h>
  13. # include <Errors.h>
  14.  
  15. #include "tcpglue.h"
  16. #include <Devices.h>
  17.  
  18. static short driver = 0;
  19.  
  20. #ifndef __powerc
  21. /*
  22.  * Hack fix for MacTCP 1.0.X bug
  23.  *
  24.  * This hack doesn't work on the PPC. But then, people with new machines
  25.  * shouldn't run ancient buggy software. -- Jack.
  26.  */
  27.  
  28. pascal char *ReturnA5(void) = {0x2E8D};
  29. #endif /* !__powerc */
  30.  
  31. OSErr xOpenDriver() 
  32.     if (driver == 0) 
  33.     { 
  34.         ParamBlockRec pb; 
  35.         OSErr io; 
  36.         
  37.         pb.ioParam.ioCompletion = 0L; 
  38.         pb.ioParam.ioNamePtr = "\p.IPP"; 
  39.         pb.ioParam.ioPermssn = fsCurPerm; 
  40.         io = PBOpen(&pb,false); 
  41.         if (io != noErr) 
  42.             return(io); 
  43.         driver = pb.ioParam.ioRefNum; 
  44.     }
  45.     return noErr;
  46. }
  47.  
  48. /*
  49.  * create a TCP stream
  50.  */
  51. OSErr xTCPCreate(buflen,notify,udp, pb) 
  52.     int buflen;
  53.     TCPNotifyUPP notify;
  54.     void *udp;
  55.     TCPiopb *pb;
  56. {    
  57.     pb->ioCRefNum = driver;
  58.     pb->csCode = TCPCreate;
  59.     pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
  60.     pb->csParam.create.rcvBuffLen = buflen;
  61.     pb->csParam.create.notifyProc = notify;
  62.     pb->csParam.create.userDataPtr = udp;
  63.     return (xPBControlSync(pb));
  64. }
  65.  
  66.  
  67. /*
  68.  * start listening for a TCP connection
  69.  */
  70. OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion,
  71.     void *udp)
  72. {
  73.     if (driver == 0)
  74.         return(invalidStreamPtr);
  75.  
  76.     pb->ioCRefNum = driver;
  77.     pb->csCode = TCPPassiveOpen;
  78.     pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
  79.     pb->csParam.open.ulpTimeoutValue = 255 /* seconds */;
  80.     pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
  81.     pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
  82.     pb->csParam.open.remoteHost = 0;
  83.     pb->csParam.open.remotePort = 0;
  84.     pb->csParam.open.localHost = 0;
  85.     pb->csParam.open.localPort = port;
  86.     pb->csParam.open.dontFrag = 0;
  87.     pb->csParam.open.timeToLive = 0;
  88.     pb->csParam.open.security = 0;
  89.     pb->csParam.open.optionCnt = 0;
  90.     pb->csParam.open.userDataPtr = udp;
  91.     return (xPBControl(pb,completion));
  92. }
  93.  
  94. /*
  95.  * connect to a remote TCP
  96.  */
  97. OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, 
  98.     TCPIOCompletionUPP completion)
  99. {
  100.     if (driver == 0)
  101.         return(invalidStreamPtr);
  102.  
  103.     pb->ioCRefNum = driver;
  104.     pb->csCode = TCPActiveOpen;
  105.     pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
  106.     pb->csParam.open.ulpTimeoutValue = 60 /* seconds */;
  107.     pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
  108.     pb->csParam.open.commandTimeoutValue = 0;
  109.     pb->csParam.open.remoteHost = rhost;
  110.     pb->csParam.open.remotePort = rport;
  111.     pb->csParam.open.localHost = 0;
  112.     pb->csParam.open.localPort = port;
  113.     pb->csParam.open.dontFrag = 0;
  114.     pb->csParam.open.timeToLive = 0;
  115.     pb->csParam.open.security = 0;
  116.     pb->csParam.open.optionCnt = 0;
  117.     return (xPBControl(pb,completion));
  118. }
  119.  
  120. OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion) 
  121.     TCPiopb *pb;
  122.     rdsEntry *rds; 
  123.     int rdslen;
  124.     int    timeout;
  125.     TCPIOCompletionUPP completion;
  126. {
  127.     
  128.     if (driver == 0)
  129.         return(invalidStreamPtr);
  130.     
  131.     pb->ioCRefNum = driver;
  132.     pb->csCode = TCPNoCopyRcv;
  133.     pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
  134.     pb->csParam.receive.rdsPtr = (Ptr)rds;
  135.     pb->csParam.receive.rdsLength = rdslen;
  136.     return (xPBControl(pb,completion));
  137. }
  138.  
  139. OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion)
  140.     {
  141.     pb->ioCRefNum = driver;
  142.     pb->csCode = TCPRcvBfrReturn;
  143.     pb->csParam.receive.rdsPtr = (Ptr)rds;
  144.     
  145.     return (xPBControl(pb,completion));
  146.     }
  147.     
  148. /*
  149.  * send data
  150.  */
  151. OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion)
  152. {
  153.     if (driver == 0)
  154.         return invalidStreamPtr;
  155.     
  156.     pb->ioCRefNum = driver;
  157.     pb->csCode = TCPSend;
  158.     pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
  159.     pb->csParam.send.ulpTimeoutValue = 60 /* seconds */;
  160.     pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
  161.     pb->csParam.send.pushFlag = push;
  162.     pb->csParam.send.urgentFlag = urgent;
  163.     pb->csParam.send.wdsPtr = (Ptr)wds;
  164.     return (xPBControl(pb,completion));
  165. }
  166.  
  167.  
  168. /*
  169.  * close a connection
  170.  */
  171. OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion) 
  172. {
  173.     if (driver == 0)
  174.         return(invalidStreamPtr);
  175.     
  176.     pb->ioCRefNum = driver;
  177.     pb->csCode = TCPClose;
  178.     pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
  179.     pb->csParam.close.ulpTimeoutValue = 60 /* seconds */;
  180.     pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
  181.     return (xPBControl(pb,completion));
  182. }
  183.  
  184. /*
  185.  * abort a connection
  186.  */
  187. OSErr xTCPAbort(TCPiopb *pb) 
  188. {
  189.     if (driver == 0)
  190.         return(invalidStreamPtr);
  191.     
  192.     pb->ioCRefNum = driver;
  193.     pb->csCode = TCPAbort;
  194.     return (xPBControlSync(pb));
  195. }
  196.  
  197. /*
  198.  * close down a TCP stream (aborting a connection, if necessary)
  199.  */
  200. OSErr xTCPRelease(pb) 
  201.     TCPiopb *pb;
  202. {
  203.     OSErr io;
  204.     
  205.     if (driver == 0)
  206.         return(invalidStreamPtr);
  207.     
  208.     pb->ioCRefNum = driver;
  209.     pb->csCode = TCPRelease;
  210.     io = xPBControlSync(pb);
  211.     if (io == noErr)
  212.         DisposPtr(pb->csParam.create.rcvBuff); /* there is no release pb */
  213.     return(io);
  214. }
  215.  
  216. #if 0
  217.  
  218. int
  219. xTCPBytesUnread(sp) 
  220.     SocketPtr sp;
  221. {
  222.     TCPiopb    *pb;
  223.     OSErr io;
  224.     
  225.     if (!(pb = sock_fetch_pb(sp)))
  226.         return -1;        /* panic */
  227.     
  228.     if (driver == 0)
  229.         return(-1);
  230.     
  231.     pb->ioCRefNum = driver;
  232.     pb->csCode = TCPStatus;
  233.     io = xPBControlSync(pb);
  234.     if (io != noErr)
  235.         return(-1);
  236.     return(pb->csParam.status.amtUnreadData);
  237. }
  238.  
  239. int
  240. xTCPBytesWriteable(sp)
  241.     SocketPtr sp;
  242.     {
  243.     TCPiopb *pb;
  244.     OSErr    io;
  245.     long    amount;
  246.     
  247.     if (!(pb = sock_fetch_pb(sp)))
  248.         return -1;        /* panic */
  249.     
  250.     if (driver == 0)
  251.         return(-1);
  252.     
  253.     pb->ioCRefNum = driver;
  254.     pb->csCode = TCPStatus;
  255.     io = xPBControlSync(pb);
  256.     if (io != noErr)
  257.         return(-1);
  258.     amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
  259.     if (amount < 0)
  260.         amount = 0;
  261.     return amount;
  262.     }
  263.     
  264. int xTCPWriteBytesLeft(SocketPtr sp)
  265.     {
  266.     TCPiopb *pb;
  267.     OSErr    io;
  268.     
  269.     if (!(pb = sock_fetch_pb(sp)))
  270.         return -1;        /* panic */
  271.     
  272.     if (driver == 0)
  273.         return(-1);
  274.     
  275.     pb->ioCRefNum = driver;
  276.     pb->csCode = TCPStatus;
  277.     io = xPBControlSync(pb);
  278.     if (io != noErr)
  279.         return(-1);
  280.     return (pb->csParam.status.amtUnackedData);
  281.     }
  282. #endif
  283.  
  284. OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb)
  285.     {
  286.     OSErr io;
  287.     
  288.     if (driver == 0)
  289.         return(-1);
  290.     
  291.     pb->ioCRefNum = driver;
  292.     pb->csCode = TCPStatus;
  293.     io = xPBControlSync(pb);
  294.     if (io == noErr)
  295.         *spb = &pb->csParam.status;
  296.     return(io);
  297.     }
  298.  
  299.  
  300. /*
  301.  * create a UDP stream, hook it to a socket.
  302.  */
  303. OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp)
  304.     {    
  305.     OSErr   io;
  306.     
  307.     pb->ioCRefNum = driver;
  308.     pb->csCode = UDPCreate;
  309.     pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
  310.     pb->csParam.create.rcvBuffLen = buflen;
  311.     pb->csParam.create.notifyProc = asr;
  312.     pb->csParam.create.userDataPtr = udp;
  313.     pb->csParam.create.localPort = *port;
  314.     if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
  315.         return io;
  316.         
  317.     *port = pb->csParam.create.localPort;
  318.     return noErr;
  319.     }
  320.  
  321. /*
  322.  * ask for incoming data
  323.  */
  324. OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionUPP completion) 
  325.     {
  326.     
  327.     if (driver == 0)
  328.         return(invalidStreamPtr);
  329.     
  330.     pb->ioCRefNum = driver;
  331.     pb->csCode = UDPRead;
  332.     pb->csParam.receive.timeOut = timeout;
  333.     pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
  334.     return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion ));
  335.     }
  336.  
  337. OSErr xUDPBfrReturn(UDPiopb *pb, char *buff) 
  338.     {
  339.     
  340.     if (driver == 0)
  341.         return(invalidStreamPtr);
  342.     
  343.     pb->ioCRefNum = driver;
  344.     pb->csCode = UDPBfrReturn;
  345.     pb->csParam.receive.rcvBuff = buff;
  346.     return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) );
  347.     }
  348.  
  349. /*
  350.  * send data
  351.  */
  352. OSErr xUDPWrite(UDPiopb    *pb,ip_addr host,ip_port port,miniwds *wds,
  353.         UDPIOCompletionUPP completion) 
  354.     {
  355.         
  356.     if (driver == 0)
  357.         return(invalidStreamPtr);
  358.     
  359.     pb->ioCRefNum = driver;
  360.     pb->csCode = UDPWrite;
  361.     pb->csParam.send.remoteHost = host;
  362.     pb->csParam.send.remotePort = port;
  363.     pb->csParam.send.wdsPtr = (Ptr)wds;
  364.     pb->csParam.send.checkSum = true;
  365.     pb->csParam.send.sendLength = 0/* must be zero */;
  366.     return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion));
  367.     }
  368.  
  369. /*
  370.  * close down a UDP stream (aborting a read, if necessary)
  371.  */
  372. OSErr xUDPRelease(UDPiopb *pb) {
  373.     OSErr io;
  374.  
  375.     if (driver == 0)
  376.         return(invalidStreamPtr);
  377.     
  378.     pb->ioCRefNum = driver;
  379.     pb->csCode = UDPRelease;
  380.     io = xPBControlSync( (TCPiopb *)pb );
  381.     if (io == noErr) {
  382.         DisposPtr(pb->csParam.create.rcvBuff);
  383.         }
  384.     return(io);
  385.     }
  386.  
  387. ip_addr xIPAddr(void) 
  388. {
  389.     struct GetAddrParamBlock pbr;
  390.     OSErr io;
  391.     
  392.     pbr.ioCRefNum = driver;
  393.     pbr.csCode = ipctlGetAddr;
  394.     io = xPBControlSync( (TCPiopb *)&pbr );
  395.     if (io != noErr)
  396.         return(0);
  397.     return(pbr.ourAddress);
  398. }
  399.  
  400. long xNetMask() 
  401. {
  402.     struct GetAddrParamBlock pbr;
  403.     OSErr io;
  404.     
  405.     pbr.ioCRefNum = driver;
  406.     pbr.csCode = ipctlGetAddr;
  407.     io = xPBControlSync( (TCPiopb *)&pbr);
  408.     if (io != noErr)
  409.         return(0);
  410.     return(pbr.ourNetMask);
  411. }
  412.  
  413. unsigned short xMaxMTU()
  414. {
  415.     struct UDPiopb pbr;
  416.     OSErr io;
  417.     
  418.     pbr.ioCRefNum = driver;
  419.     pbr.csCode = UDPMaxMTUSize;
  420.     pbr.csParam.mtu.remoteHost = xIPAddr();
  421.     io = xPBControlSync( (TCPiopb *)&pbr );
  422.     if (io != noErr)
  423.         return(0);
  424.     return(pbr.csParam.mtu.mtuSize);
  425. }
  426.  
  427. OSErr xPBControlSync(TCPiopb *pb) 
  428.     (pb)->ioCompletion = 0L; 
  429.     return PBControl((ParmBlkPtr)(pb),false); 
  430. }
  431.  
  432. #pragma segment SOCK_RESIDENT
  433.  
  434. OSErr xTCPRcv(pb,buf,buflen,timeout,completion) 
  435.     TCPiopb *pb;
  436.     Ptr buf; 
  437.     int buflen;
  438.     int    timeout;
  439.     TCPIOCompletionUPP completion;
  440. {
  441.     
  442.     if (driver == 0)
  443.         return(invalidStreamPtr);
  444.     
  445.     pb->ioCRefNum = driver;
  446.     pb->csCode = TCPRcv;
  447.     pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
  448.     pb->csParam.receive.rcvBuff = buf;
  449.     pb->csParam.receive.rcvBuffLen = buflen;
  450.     return (xPBControl(pb,completion));
  451. }
  452.  
  453. OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion) 
  454. #ifndef __MWERKS__
  455.     pb->ioNamePtr = ReturnA5();
  456. #endif
  457.     
  458.     if (completion == 0L) 
  459.     { 
  460.         (pb)->ioCompletion = 0L; 
  461.         return(PBControl((ParmBlkPtr)(pb),false));        /* sync */
  462.     } 
  463.     else if (completion == (TCPIOCompletionUPP)-1L) 
  464.     { 
  465.         (pb)->ioCompletion = 0L; 
  466.         return(PBControl((ParmBlkPtr)(pb),true));        /* async */
  467.     } 
  468.     else 
  469.     {  
  470.         (pb)->ioCompletion = completion;
  471.         return(PBControl((ParmBlkPtr)(pb),true));        /* async */
  472.     } 
  473. }
  474.  
  475.